#include "wds_pickup.h"
#include "wds_sfx_manager.h"
#include "wds_pickup_manager.h"
#include "wds_sounds.h"
#include "wds_enemy_manager.h"
#include "wds_bullet_manager.h"
#include "wds_enemy_collection.h"

#include "dd/dd_man.h"
#include "math/math_core.h"
#include "math/facing.h"
#include "num/rand.h"



WDSPickup::WDSPickup(WDSPickup::PICKUP_TYPES Type,const math::Vec2& P): 
								m_Pos(P),
								m_Type(Type),
								m_Rotation(0.0f),
								m_AnimationState(PICKUP_ANIMATION_STATE_NONE),
								m_pSFX(NULL),
								m_RotationSpeed(0),
								m_Scale(1.0f)
{
	LoadSprite();	

}
	


std::string		WDSPickup::GetSpriteFile1(PICKUP_TYPES Type)
{
	switch(Type)
	{
		
		case PICKUP_TYPE_HEALTH:
			return "pickup_medikit";			
		
		case PICKUP_TYPE_NUKE:
		    return "pickup_nuke";
		
		case PICKUP_TYPE_SHIELD:
			return "pickup_shield";
		
		case PICKUP_TYPE_STAR:
			return "star_pick_up_item";
		
		case PICKUP_TYPE_1UP:
			return "player_up_item";

		case PICKUP_TYPE_FLASHSTEP:
			return "pickup_flashstep";

		case PICKUP_TYPE_MOVESPEED:
			return "pickup_movespeed";

		case PICKUP_TYPE_WEAPONSPEED:
			return "pickup_wepSpeed";

		case PICKUP_TYPE_FREEZE:
			return "pickup_freeze";

		case PICKUP_TYPE_FIREBLAST:
			return "pickup_fireblast";

		case PICKUP_TYPE_FIREBULLETS:
			return "pickup_firebullets";

		case PICKUP_TYPE_ASSAULTRIFLE:
			return "assault_rifle";

		case PICKUP_TYPE_SHOTGUN:
			return "shotgun";

		case PICKUP_TYPE_SAWEDOFFSHOTGUN:
			return "sawed_off_shotgun";

		case PICKUP_TYPE_SUBMACHINEGUN:
			return "submachine";

		case PICKUP_TYPE_GAUSSGUN:
			return "gauss";

		case PICKUP_TYPE_MEANMINIGUN:
			return "mean_mini";

		case PICKUP_TYPE_FLAMETHROWER:
			return "flame_thrower";

		case PICKUP_TYPE_PLASMARIFLE:
			return "plasma_rifle";

		case PICKUP_TYPE_MULTIPLASMAGUN:
			return "multi_plasma	";

		case PICKUP_TYPE_PLASMAMINIGUN:
			return "plasma_mini";

		case PICKUP_TYPE_ROCKETLAUNCHER:
			return "rocket_launcher";

		case PICKUP_TYPE_SEEKERROCKET:
			return "seeker_rocket";

		case PICKUP_TYPE_PLASMASHOTGUN:
			return "plasma_shotgun";

		case PICKUP_TYPE_MINIROCKETSWARMER:
			return "mini_rocket_swarmer";

		case PICKUP_TYPE_ROCKETMINIGUN:
			return "rocket_mini";

		case PICKUP_TYPE_PULSEGUN:
			return "pulse";

		case PICKUP_TYPE_JACKHUMMER:
			return "jack_hammer";

		case PICKUP_TYPE_IONRIFLE:
			return "ion_rifle";

		case PICKUP_TYPE_IONMINIGUN:
			return "ion_mini";

		case PICKUP_TYPE_IONCANNON:
			return "ion_cannon";

		case PICKUP_TYPE_PLASMACANNON:
			return "plasma_cannon";

		case PICKUP_TYPE_GAUSSSHOTGUN:
			return "gauss_shotgun";

		case PICKUP_TYPE_IONSHOTGUN:
			return "ion_shotgun";


		
	}
	return "";
}

std::string		WDSPickup::GetSpriteFile2(PICKUP_TYPES Type)
{
	switch(Type)
	{ 		
		case PICKUP_TYPE_HEALTH:
			return "red_cross"; 			
		break;		
	}
	return "";
}


void	WDSPickup::LoadSprite()
{
	Load(GetSpriteFile1(m_Type),GetSpriteFile2(m_Type));

	switch(m_Type)
	{
		case PICKUP_TYPE_HEALTH:		
			m_RotationSpeed = 0.1f;
			break;
			
		default:
			m_RotationSpeed = 0;
			break;
	}                   	
}


void	WDSPickup::Load(const std::string& Name,const std::string& Glow)
{
	m_Sprite.Create(Name);		
	m_Radius = m_Sprite.m_SizeOriginal.x * 0.5f;
}

void	WDSPickup::Render(const math::Vec2& Offset, float Scale)
{
	if(!m_IsAlive)
		return;

	m_Sprite.m_Pos = m_Pos - Offset;
	m_Sprite.m_Size = m_Sprite.m_SizeOriginal * m_Scale * Scale;
	m_Sprite.m_Rotation = m_Rotation;
	m_Sprite.RenderRotated();
	
}
	
void	WDSPickup::RenderDebug(const math::Vec2& Offset, float Scale)
{
	if(!m_IsAlive)
		return;	
    	
	dd::Manager&	DD = dd::Manager::Instance();
	DD.AddCircle2D( m_Pos+Offset, m_Radius*Scale, ColorRGBA(255,0,0) );	
}
	
void	WDSPickup::Tick(float dt)
{
	if(m_IsAlive)
	{
		if( m_Duration > 0)
			m_Duration -= dt;

		if(m_Duration <= 0)
		{
			m_AnimationState = PICKUP_ANIMATION_STATE_DISAPPEAR;
		}
	}

	switch( m_AnimationState)
	{
		case PICKUP_ANIMATION_STATE_GOINGSMALL:
			m_Scale -= ( dt * 0.2f);
			if( m_Scale <= 0.9f)
			{	
				m_Scale = 0.9f;
				m_AnimationState = PICKUP_ANIMATION_GOINGBIG;
			}	
		break;

		case PICKUP_ANIMATION_GOINGBIG:
			m_Scale += ( dt * 0.2f);
			if( m_Scale >= 1.1f)
			{	
				m_Scale = 1.1f;
				m_AnimationState = PICKUP_ANIMATION_STATE_GOINGSMALL;
			}	
		break;

		case PICKUP_ANIMATION_STATE_APPEAR_START:
			m_AnimationState = PICKUP_ANIMATION_STATE_APPEAR;
			m_Scale = 0.0f;
		break;

		case PICKUP_ANIMATION_STATE_APPEAR:
			m_Scale += dt;
			if( m_Scale >= 1.0f)
			{
				m_Scale = 1.0f;
				m_AnimationState = PICKUP_ANIMATION_STATE_GOINGSMALL;
			}
			
		break;

		case PICKUP_ANIMATION_STATE_DISAPPEAR_START:

		break;

		case PICKUP_ANIMATION_STATE_DISAPPEAR:
			m_Scale -= dt;
			if( m_Scale <= 0.0f)
			{	
				m_Scale = 0.0f;
				m_IsAlive = false;
			}	
		break;

		case PICKUP_ANIMATION_STATE_C:

		break;

	}
	
}

	
	

void		WDSPickup::ReSpawn()
{
	
	if(m_pSFX)
	{
		// clean previous sfx if any
		m_pSFX->ToDie();
		m_pSFX = NULL;
	}
	
	m_AnimationState = PICKUP_ANIMATION_STATE_APPEAR_START;
	
	
    m_IsAlive = true;
	m_Duration = 10.0f;
	//m_pSFX = WDSSFXManager::Instance().Spawn(WDSSfx::SFX_NONE ,m_Pos , 1.0f);
}
	
void		WDSPickup::RenderShadow(const math::Vec2& Offset, float Scale)
{

}
	

void		WDSPickup::OnDie()
{

}

WDSPickup::PICKUP_TYPES		WDSPickup::HitTest(const math::Vec2& P, float Radius, float Scale)
{

	if(m_AnimationState == PICKUP_ANIMATION_STATE_APPEAR_START ||
		m_AnimationState == PICKUP_ANIMATION_STATE_APPEAR ||
		( m_AnimationState == PICKUP_ANIMATION_STATE_DISAPPEAR && m_Scale < 0.5f)
		)
		return PICKUP_TYPE_NONE;

	if(!m_IsAlive)
		return PICKUP_TYPE_NONE;

	if( (m_Pos - P).Magnitude() < (m_Radius + Radius) * Scale )
	{
		GotEaten();
		return m_Type;
	}
	
	return PICKUP_TYPE_NONE;
}

void		WDSPickup::GotEaten()
{
	m_IsAlive = false;
	switch(m_Type)
	{
		case PICKUP_TYPE_STAR:  		
			WDSSounds::Instance().PlaySoundSFX(WDSSounds::SFX_NONE);
		break;

		case PICKUP_TYPE_SHIELD:
			WDSSounds::Instance().PlaySoundSFX(WDSSounds::SFX_NONE);  		
		break;

		case PICKUP_TYPE_HEALTH:
		case PICKUP_TYPE_1UP:
			WDSSounds::Instance().PlaySoundSFX(WDSSounds::SFX_NONE);  		
		break;

	
		default:
			WDSSounds::Instance().PlaySoundSFX(WDSSounds::SFX_NONE);
		break;

		case PICKUP_TYPE_FIREBLAST:

			for(int i = 0; i < 8; i++)
				WDSBulletManager::Instance().Shoot(WDSBullet::BULLET_TYPE_FIRE,NULL ,m_Pos, i * 45.0f, WDSSounds::SFX_NONE);
			

		break;

		case PICKUP_TYPE_FREEZE:
			WDSEnemyManager::Instance().Freeze();
		break;

		case PICKUP_TYPE_NUKE:
		{
			WDSSFXManager::Instance().Spawn(WDSSfx::SFX_NUKE, m_Pos, 1.0f);
			// now damage to enemy near this explosion

			const float EFFECT_RADIUS = 0.3f;
			const float NUKE_DAMAGE = 100.0f;
			std::vector<WDSEnemyCollection*>	EnemyCollection;
			WDSEnemyManager::Instance().GetEnemyCollection(EnemyCollection);
			math::Vec2 Pos1 = m_Pos;
			math::Movement::ChangeToSquareVec2(Pos1);
			math::Vec2 Pos2;

			for(int i = 0; i < (int)EnemyCollection.size(); i++)
			{
				WDSEnemyCollection* pCol = EnemyCollection[i];
				for(int j = 0; j < (int)pCol->GetCount(); j++)
				{
					WDSEnemy* pEnemy = pCol->GetEnemyByIndex(j);					

					if(!pEnemy->IsAlive())
						continue;
					
					Pos2 = pEnemy->GetPos();
					math::Movement::ChangeToSquareVec2(Pos2);
					
					if((Pos2 - Pos1).Magnitude() <= EFFECT_RADIUS)
					{
						pEnemy->GotDamaged(NUKE_DAMAGE, NULL, false);
					}
				}
			}
		}
		break;


	}
	

	

}

void		WDSPickup::Clear()
{
	if(m_pSFX)
	{
		m_pSFX->ToDie();
		m_pSFX = NULL;
	}
}


bool		WDSPickup::IsInSideScreen()
{
	return true;
}


std::string		WDSPickup::MapTypeToName(WDSPickup::PICKUP_TYPES Type)
{
	switch(Type)
	{
		case PICKUP_TYPE_HEALTH:
		return	"HEALTH";
	
		
		case PICKUP_TYPE_SHIELD:
			return "ARMOR";

		case PICKUP_TYPE_STAR:
			return "STAR";
	
		case PICKUP_TYPE_NUKE:
			return "NUKE";	

		case PICKUP_TYPE_1UP:
			return "1UP";

		default:
			break;
	}
    
	return "unknown";

}

WDSPickup::PICKUP_TYPES		WDSPickup::MapNameToType(const std::string& TypeName)
{
	for (unsigned int i = 0; i < PICKUP_COUNT; i++)
		if (strcmpi( MapTypeToName((PICKUP_TYPES)i).c_str(), TypeName.c_str() ) == 0)
			return (PICKUP_TYPES)i;

	return PICKUP_TYPE_NONE; 
	
}

